package ui;

import indexer.ReverseIndex;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import searcher.Hit;
import searcher.HitSet;
import searcher.NittySearcher;
import searcher.Request;
import util.Constants;
import util.Summary;
import util.benchmark.BenchMarker;
import util.benchmark.Clock;
import algorithm.text.wordsegment.WordSegmentor;

public class ConsoleUI {
	public static final int WS_ALGORITHM = WordSegmentor.ALGORITHM_DYNAMIC;
	public static final int MAX_SENTENCE_LEN_FOR_SUMMARY = 160;
	private static final ReverseIndex ri;
	private static final WordSegmentor ws;
	private static final Summary summary;
	//below is changed by shitgao, he wants to see how NittySearcher works
	//private static final NaiveSearcher searcher;
	private static final NittySearcher searcher;
	
	private static final Clock clockQuery = BenchMarker.getClock("query");
	private static final Clock clockWs = BenchMarker.getClock("ws");
	
	static {
		summary = new Summary();
		summary.setSummaryLength(MAX_SENTENCE_LEN_FOR_SUMMARY);
		ri = new ReverseIndex();
		ws = new WordSegmentor(Constants.DIC_FOLDER, Constants.SINGLE_LETTER_WORD_FILENAME);
		//changed by shitgao
		//searcher = new NaiveSearcher(ri);
		searcher = new NittySearcher(ri);
	}
	
	public static void main(String[] args) throws IOException {
		loadIndexData();
		System.out.println("------------------------------");
		System.out.println("Tiny Searcher v0.1");
		System.out.println("------------------------------");
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String line;
		System.out.print(">> ");
		long lastWs = 0;
		long lastQy = 0;
		while ((line = br.readLine()) != null) {
			if (line.length() == 0)
				continue;
			if (line.toUpperCase().equals("EXIT"))
				break;
			lastWs = clockWs.getTotalTime();
			clockWs.cont();
			List<String> parsedQuery = ws.segmentToWords(line, 0, line.length(), WS_ALGORITHM);
			clockWs.pause();
			System.out.println("------------------------------------------");
			lastQy = clockQuery.getTotalTime();
			outputSearchResult(line, parsedQuery);
			System.out.println(parsedQuery);
			System.out.println("Time: [word segmentor] " + (clockWs.getTotalTime() - lastWs) + "ms. " +
					"[Query] " + (clockQuery.getTotalTime() - lastQy) + "ms.");
			System.out.println("------------------------------------------");
			System.out.print(">> ");
		}
		System.out.println(BenchMarker.getTextReport());
	}

	/**
	 * 用空格隔开，用于给Summary
	 * @return
	 */
	private static String combineQuery(List<String> parsedQuery) {
		StringBuilder sb = new StringBuilder();
		sb.append(parsedQuery.get(0));
		for (int i = 1; i < parsedQuery.size(); i++) {
			sb.append(' ');
			sb.append(parsedQuery.get(i));
		}
		return sb.toString();
	}
	/**
	 * 输出搜索结果
	 * @param ret
	 * @param out 
	 */
	//shitgao modified this method to see if NittySearcher works
	private static void outputSearchResult(String query, List<String> parsedQuery) {
		//below is changed by shitgao
		String combinedQuery = combineQuery(parsedQuery);
		clockQuery.cont();
		//HitSet queryResults = searcher.getSearchResult(new Request(combinedQuery));
		HitSet queryResults=searcher.getSearchResult(new Request(query));
		//above is changed by shitgao
		clockQuery.pause();
		if (queryResults == null) {
			System.out.println("Sorry, no results found");
			return;
		}
		for (Hit result : queryResults) {
			String content = getTextFileContent(result.fileName);
			System.out.println(summary.getSummary(combinedQuery, content));
			System.out.println();
		}
		System.out.println("total = " + queryResults.size());
	}

	private static String getTextFileContent(String fileName) {
		BufferedReader br;
		try {
			br = new BufferedReader(
					new InputStreamReader(new FileInputStream(fileName), "utf-8"));
			StringBuilder sb = new StringBuilder();
			String line;
			while ((line = br.readLine()) != null) {
				// ignore useless lines
				if (line.length() == 0 || line.startsWith(":") || 
						line.startsWith("发信站: 水木社区") || 
						(line.startsWith("【") && line.endsWith("】")))
					continue;
				if (line.startsWith("发信人: ")) {
					// author
					int pos = line.indexOf(',');
					line = line.substring(4, pos);
				} else if (line.startsWith("标  题: ")) {
					// title
					line = line.substring(4);
				}
				sb.append(line);
				sb.append('\n');
			}
			br.close();
			return sb.toString();
		} catch (FileNotFoundException e) {
			System.err.println("File " + fileName + " not found!");
			e.printStackTrace();
		} catch (IOException e) {
			System.err.println("Error opening file " + fileName);
			e.printStackTrace();
		}
		return "<<NO CONTENT>>";
	}

	/**
	 * 读入Index的数据
	 * @throws IOException 
	 */
	private static void loadIndexData() throws IOException {
		File dataDir = new File(Constants.INDEX_FOLDER);
		if (!dataDir.exists()) {
			System.out.print("Index[" + Constants.INDEX_FOLDER + 
					"] does NOT exist, building...");
			ri.indexDirectory(Constants.ORIGINAL_FILE_FOLDER, true);
			System.out.println("OK!");
			System.out.print("storing to " + Constants.INDEX_FOLDER + " for future use");
			ri.storeIndex(Constants.INDEX_FOLDER);
			System.out.println("OK!");
		} else {
			if (!dataDir.isDirectory()) {
				System.err.println("Error: index dir is not a directory!");
			}
			System.out.print("Loading " + Constants.INDEX_FOLDER);
			ri.loadIndex(Constants.INDEX_FOLDER);
			System.out.println("OK!");
		}
	}
}